home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX350 / HDX.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  38.7 KB  |  1,646 lines

  1. /* hdx.c */
  2.  
  3. /*
  4.  * Atari Hard Disk Installation Utility
  5.  * Copyright 1988 Atari Corp.
  6.  *
  7.  * Associated files
  8.  *    hdx.rsc        resource file
  9.  *    wincap        hard disk database (text file)
  10.  *
  11.  *    hdx.h        object tree definitions
  12.  *    defs.h        constant definitions
  13.  *    part.h        ST structure definitions
  14.  *    ipart.h        IBM structure definitions
  15.  *
  16.  *    hdx.c        top level, user interface (this file)
  17.  *    epart.c        edit partition sizes
  18.  *    fmt.c        disk formatting
  19.  *    part.c        partition reading/writing
  20.  *    sect.c        sector reading, writing, zeroing
  21.  *    string.c    string functions (matching, concat, ...)
  22.  *    assist.c    markbad(), zero()
  23.  *    wincap.c    hard disk parameter / partition size database
  24.  *    st.c        random ST functions (delay, reboot, ...)
  25.  *
  26.  *----
  27.  * 11-May-1988    ml.    Cleaned up the memory management in the program
  28.  *            (ie. for all files).  Memory chunks which are for
  29.  *            sure will be < 32k is allocated using malloc(),
  30.  *            whereas chunks >= 32k is allocated using Malloc().
  31.  *            When using malloc(), you will get the 'Stack Over-
  32.  *            flow message if you are in Supervisor mode and 
  33.  *            you have your own supervisor stack.  To get around
  34.  *            this, have to use mymalloc() (in mymalloc.s).
  35.  * 15-Mar-1988    ml.    Changed interface to Markbad.
  36.  * 11-Jan-1988    ml.    Modified dialogue boxes.
  37.  * 07-Dec-1987    ml.    Started to add in concept of Bad Sector List.
  38.  * ??-Oct-1987  ml.    Partition and Disk type menu now has 15 entries 
  39.  *            instead of 16.
  40.  * 30-Sep-1987    ml.    Inherited 'this' from Landon Dyer.
  41.  * 24-Mar-1986 lmd    Released to software test.
  42.  * 15-Mar-1986 lmd    Hacked up from earlier version by Jim Tittsler.
  43.  * 8-Nov-1988  jye. change and add some codes so that can be used for extended
  44.  *                    and big partition.
  45.  * 13-Jun-1989 jye. Change and add some codes so that HDX can be deal with
  46.  *                    acsi and scsi drives.
  47.  * 22-Jan-1990 jye. Change the HDX so that we don't have to put a informations
  48.  *                    of a drive into the Wincap file.
  49.  * 13-Mar-1990 jye. change the HDX to a genetic one so that the user don't
  50.  *                    need know what kind of drive.
  51.  * 20-Jul-1990 jye. change the interface about the unit select. In the new 
  52.  *                    interface, user tells the type of drive is acsi or scsi,
  53.  *                    then selects unit.
  54.  * 01-Aug-1990 jye. Change hard disk size request from mdsence to readcap.
  55.  *
  56.  */
  57.  
  58. #include "obdefs.h"
  59. #include "gemdefs.h"
  60. #include "osbind.h"
  61. #include "mydefs.h"
  62. #include "part.h"
  63. #include "bsl.h"
  64. #include "hdx.h"
  65. #include "ipart.h"
  66. #include "addr.h"
  67. #include "error.h"
  68.  
  69. #define MFM 17
  70.  
  71. extern char sbuf[];
  72. extern int rebootp;
  73. extern long gbslsiz();
  74. extern long get3bytes();
  75. extern long get4bytes();
  76. extern long bslsiz;
  77. extern BYTE *bsl;
  78. extern int uplim;            /* the number of partitions */
  79. extern long sptrk;
  80. extern long spcyl;
  81. extern int ibmpart;
  82. extern int yesscan;
  83. extern long disksiz;
  84. extern long ratio;
  85. extern int typedev;
  86. extern int typedrv;
  87. extern int prevnpart;
  88.  
  89. /* Globals */
  90. int rebootp = 0;    /* 1: must reboot (not return to desktop) */
  91. int tformat;            /* TRUE: just formatted disk */
  92. int running;        /* 1: continue evnt_multi() loop */
  93. char sbuf[512];        /* error message buffer */
  94. long extsiz;        /* the size of extened partition */
  95. long ostack;                /* old stack pointer */
  96. int toibm;            /* the flag of partition to ibm format */
  97. int ibm2st;            /* the flag for IBM partition to ST */
  98. long bps;            /* bytes per sector */
  99. int npart;            /* number of partition */
  100. int ext;            /* the index of extended partition */
  101. int extend;            /* the index of end extended partition */
  102. int showmany;        /* the flag that show the too much device alert box */
  103. char ttscsi;        /* SCSI hard disk drive */
  104. int needscan;        /* TRUE: if info in the LOGMAP update */
  105. int noinfo;            /* 1: no informations in the wincap */
  106.  
  107. /*  Logical-to-dev+partition mapping table. */
  108. extern int nlogdevs;        /* #logical devs found */
  109. extern LOGMAP logmap[];        /* logical dev map */
  110. extern int livedevs[];        /* live physical dev flag */
  111. extern char cachexst;        /* 0: no cache. 1: with cache */
  112.  
  113. /* Partition related variables */
  114. long mxpsiz = MAXPSIZ;
  115.  
  116. /* AES (windows and messages) related variables */
  117. int gl_hchar;        /* height of system font (pixels) */
  118. int gl_wchar;        /* width of system font (pixels) */
  119. int gl_wbox;        /* width of box able to hold system font */
  120. int gl_hbox;        /* height of box able to hold system font */
  121.  
  122. int phys_handle;    /* physical workstation handle */
  123. int handle;        /* virtual workstation handle */
  124. int wi_handle;        /* window handle */
  125.  
  126. int formw, formh, sx, sy, lx, ly;    /* dialogue box dimensions */
  127. int xdesk, ydesk, hdesk, wdesk;        /* window X, Y, width, height */
  128. int xwork, ywork, hwork, wwork;        /* desktop and work areas */
  129.  
  130. int msgbuff[8];        /* event message buffer */
  131. int keycode;        /* keycode returned by event-keyboard */
  132. int mx, my;        /* mouse x and y pos. */
  133. int butdown;        /* button state tested for, UP/DOWN */
  134. int ret;        /* dummy return variable */
  135. int pnf;        /* 1: partition or format; 0: zero or markbad */
  136. int hidden;        /* current state of cursor */
  137. int contrl[12];
  138. int intin[128];
  139. int ptsin[128];
  140. int intout[128];
  141. int ptsout[128];    /* storage wasted for idiotic bindings */
  142. int work_in[11];    /* Input to GSX parameter array */
  143. int work_out[57];    /* Output from GSX parameter array */
  144. int pxyarray[10];    /* input point array */
  145.  
  146. /*
  147.  * Top level;
  148.  * we get control from the desktop.
  149.  */
  150. main()
  151. {
  152.     pnf = 0;        /* set the flag to it isn't partition yet */
  153.     appl_init();
  154.     phys_handle=graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
  155.     wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
  156.     open_vwork();
  157.     wi_handle=wind_create(0x0040&0x0080, xdesk, ydesk, wdesk, hdesk);
  158.  
  159.     hidden = FALSE;
  160.     butdown = TRUE;
  161.  
  162.     /* doing a checking see if the cache in the system */
  163.     cachexst = (char) chkcache();
  164.  
  165.     if (!rsrc_load(RESOURCEFILE)) {
  166.     errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  167.     goto punt;
  168.     }
  169.  
  170.     
  171.     /* Get all addresses of dialogues from resource file */
  172.     if (getalladdr() != OK) {
  173.     errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  174.     goto punt;
  175.     }
  176.  
  177.  
  178.     /*
  179.      * Get maximum partition size from
  180.      * wincap "@@" entry.
  181.      */
  182.     /*
  183.     if (wgetent("Parameters", "@@") == OK) {
  184.     if (wgetnum("ms", &mxpsiz) != OK)
  185.         mxpsiz = MAXPSIZ;
  186.     } else {
  187.         goto punt;
  188.     }
  189.     */
  190.  
  191.     needscan = TRUE;
  192.  
  193. redomul:
  194.     ARROW_MOUSE;
  195.  
  196.     /* display menu bar */
  197.     menu_bar(menuobj, 1);
  198.  
  199.     running = TRUE;
  200.     while (running) {
  201.         domulti();
  202.     }
  203.  
  204.     /*
  205.      * If nothing has been done to the hard disks
  206.      * then just get out, back to the desktop.
  207.      * Otherwise reboot the system.
  208.      */
  209.     menu_bar(menuobj, 0);        /* erase menu bar */
  210.  
  211. punt:
  212.     /*
  213.      * If we have to reboot,
  214.      * tell the user and then do it.
  215.      *
  216.      */
  217.     if (rebootp) {
  218.         if (form_alert(2, autoboot) == 1)    {
  219.             reboot();
  220.         } else {
  221.             goto redomul;
  222.         }
  223.     }
  224.  
  225.     wind_delete(wi_handle);
  226.     v_clsvwk(handle);
  227.     appl_exit();
  228. }
  229.  
  230.  
  231. /*
  232.  * Get a single event, process it, and return.
  233.  *
  234.  */
  235. domulti(){
  236.     int event;
  237.     
  238.     event = evnt_multi(MU_MESAG,
  239.             1,1,butdown,
  240.             0,0,0,0,0,
  241.             0,0,0,0,0,
  242.             msgbuff,0,0,&mx,&my,&ret,&ret,&keycode,&ret);
  243.  
  244.     if (event & MU_MESAG) {
  245.         wind_update(TRUE);
  246.     switch (msgbuff[0]) {
  247.         case WM_REDRAW:
  248.         do_redraw(msgbuff[4],msgbuff[5],msgbuff[6],msgbuff[7]);
  249.         break;
  250.  
  251.         case MN_SELECTED:
  252.             BEE_MOUSE;
  253.         switch(msgbuff[3]) {
  254.             case MNDISK:
  255.             switch (msgbuff[4]) {
  256.                 case DIFORM:
  257.                     if ((needscan) && (rescan(0,0) == ERROR))    {
  258.                         break;    /* don't report medium changed */
  259.                     }
  260.                     tformat = TRUE;
  261.                     needscan = FALSE;
  262.                     dodiform();
  263.                     tformat = FALSE;
  264.                     break;
  265.                 case DIPART:
  266.                     if ((needscan)&&(rescan(0,0) == ERROR))    {
  267.                         break;    /* don't report medium changed */
  268.                     }
  269.                     needscan = FALSE;
  270.                     dodipart(-1, NULL, NULL);
  271.                     break;
  272.                 case DIZERO:
  273.                     if (pnf)    {
  274.                         err(needboot);
  275.                     } else {
  276.                         if ((needscan)&&(rescan(0,1) == ERROR))    {
  277.                             break;    /* don't report medium changed */
  278.                         }
  279.                         needscan = FALSE;
  280.                         dodizero();
  281.                     }
  282.                     break;
  283.                 case DIMARK:
  284.                     if (pnf)    {
  285.                         err(needboot);
  286.                     } else {
  287.                         if ((needscan)&&(rescan(0,1) == ERROR))    {
  288.                             break;    /* don't report medium changed */
  289.                         }
  290.                         needscan = FALSE;
  291.                         dodimark();
  292.                     }
  293.                     break;
  294.                 case DISHIP:
  295.                     if ((needscan)&&(rescan(0,0) == ERROR))    {
  296.                         break;    /* don't report medium changed */
  297.                     }
  298.                     needscan = FALSE;
  299.                     dodiship();
  300.                     break;
  301.                 default:        break;
  302.             }
  303.             break;
  304.  
  305.             case MNFILE:
  306.             switch (msgbuff[4]) {
  307.                 case FIQUIT:
  308.                 running = 0;
  309.                 break;
  310.  
  311.                 default:
  312.                 break;
  313.             }
  314.             break;
  315.             
  316.             case MNDESK:
  317.             if(msgbuff[4] == DEABOUT) {
  318.                 strcpy(abtdial[ABVERSN].ob_spec, "Version 3.5");
  319.                 abtdial[ABOK].ob_state = NORMAL;
  320.                 execform(abtdial);
  321.             }
  322.             break;        /* "cannot happen" */
  323.         }
  324.  
  325.         menu_tnormal(menuobj, msgbuff[3], 1);    /* back to normal */
  326.             ARROW_MOUSE;
  327.         break;
  328.         
  329.         case WM_NEWTOP:
  330.         case WM_TOPPED:
  331.         wind_set(wi_handle, WF_TOP, 0, 0, 0, 0);
  332.         break;
  333.  
  334.         case WM_CLOSED:
  335.         running = FALSE;
  336.         break;
  337.  
  338.         default:
  339.         break;
  340.     }
  341.     wind_update(FALSE);
  342.     }
  343. }
  344.  
  345.  
  346. /*
  347.  * Default partition name (no "pt" entry).
  348.  */
  349. #define    DEF_PARTNAME    "4-6-10"
  350.  
  351.  
  352. /*
  353.  * Map from button in format dial.
  354.  */
  355. int pfmt[] = {
  356.     PFMT0, PFMT1, PFMT2, PFMT3,
  357.     PFMT4, PFMT5, PFMT6, PFMT7,
  358.     PFMT8, PFMT9, PFMT10, PFMT11,
  359.     PFMT12, PFMT13, PFMT14, PFMT15
  360. };
  361.  
  362.  
  363. /*
  364.  * Handle [FORMAT] item.
  365.  *
  366.  */
  367. dodiform()
  368. {
  369.   extern char bootstop;
  370.   extern char bootend;
  371.   int dev, v, w, i, br;
  372.   int modesel;            /* flag for mode select */
  373.   long cnt, hdsiz;
  374.   char *s, *d, *wgetstr();
  375.   char buf[10], bs[512], sendata[32];
  376.   char pnam[128];
  377.   char *seldev = "X", *id = "XXXXX";
  378.   HINFO hinfo;
  379.   char devnames[NAMSIZ];    /* device type name buffer */
  380.   long nbad;
  381.   extern long gbslsiz(), nument(), dsmarkbad();
  382.   long pattern, temp;
  383.   long longrandom();
  384.   char pr_id[10];    /* partition scheme id */
  385.   int mask = 0x0001;
  386.   int set, scsidrv, bsiz, other = 0;
  387.   
  388.   /*
  389.    * Throw up generic formatting/partition warning,
  390.    * then get physical dev they want to clobber.
  391.    */
  392.   yesscan = 0;
  393.   noinfo = 0;
  394.   for (i = 0; i < NAMSIZ; i++)
  395.       devnames[i] = "\0";
  396.   fwarning[FWARNCN].ob_state = NORMAL;
  397.   fwarning[FWARNOK].ob_state = NORMAL;
  398.   if (execform(fwarning) != FWARNOK) return BAILOUT;
  399.  
  400.   if ((dev = gphysdev()) < 0) {
  401.       return BAILOUT;
  402.   }
  403.   strcpy(id, "mn");
  404.   br = 0;
  405.  
  406.   /* display doing SCSI massage */
  407.  
  408.   if (dev > 7)  {    /* do the SCSI drive */
  409.       noinfo = 1;
  410.       goto stfm;
  411.   }
  412.   
  413.   inqfmt:
  414.   /* Get all available disk types from wincap 'mn' entries */  
  415.   wallents(devnames, id);
  416.   if (!*devnames)     {
  417.       noinfo = 1;
  418.       goto stfm;
  419.   }
  420.   
  421.   /* Shove format name text into buttons */
  422.   for (i = 0, s = devnames; i < 14 && *s; ++i) {
  423.       dsknames[pfmt[i]].ob_type = G_BUTTON;    /* button */
  424.       dsknames[pfmt[i]].ob_spec = (long)s;
  425.       dsknames[pfmt[i]].ob_state = NORMAL;
  426.       dsknames[pfmt[i]].ob_flags = SELECTABLE | RBUTTON;
  427.       while (*s++)
  428.     ;
  429.   }
  430.   other = i;                            /* the other button */
  431.   dsknames[pfmt[i]].ob_type = G_BUTTON;    /* button */
  432.   dsknames[pfmt[i]].ob_spec = "OTHER";
  433.   dsknames[pfmt[i]].ob_state = NORMAL;
  434.   dsknames[pfmt[i]].ob_flags = SELECTABLE | RBUTTON;
  435.   i++;
  436.  
  437.   /* rest of buttons are invisible and untouchable */
  438.   for (; i < 16; ++i) {
  439.       dsknames[pfmt[i]].ob_type = G_IBOX;    /* invisible box */
  440.       dsknames[pfmt[i]].ob_spec = 0;        /* no thickness */
  441.       dsknames[pfmt[i]].ob_state = DISABLED;    /* nobody home */
  442.       dsknames[pfmt[i]].ob_flags = NONE;        /* disabled */
  443.   }
  444.   
  445.   /* clean up rest of the form and throw it up */
  446.   dsknames[PFOK].ob_state = NORMAL;
  447.   dsknames[PFCN].ob_state = NORMAL;
  448.   if (execform(dsknames) != PFOK)
  449.     return BAILOUT;
  450.   
  451.   /* search for format they picked */
  452.   for (i = 0; i < 16; ++i)
  453.     if (dsknames[pfmt[i]].ob_state & SELECTED)
  454.       break;
  455.   if (i >= 16) {        /* nothing picked */
  456.       return BAILOUT;
  457.   } else if (other == i)    {  /* the OTHER button was selected */
  458.         noinfo = 1;
  459.       goto stfm;
  460.   }
  461.   
  462.     if ((!br) && (dev < 8))        {
  463.           if (wgetent(dsknames[pfmt[i]].ob_spec, "mn") == ERROR)    {
  464.             nofmt[NOSCHFMT].ob_spec = dsknames[pfmt[i]].ob_spec;
  465.             nofmt[NOSCHFMT].ob_state = NORMAL;
  466.             execform(nofmt, 0);
  467.             return ERROR;
  468.         }
  469.         if ((s = wgetstr("br")) != NULL)    {
  470.             strcpy(id, s);
  471.             br = 1;            /* processing the branch */
  472.             goto inqfmt;    /* start over */
  473.         }
  474.     }
  475.  
  476. stfm:
  477.     modesel = 1;
  478.   if (gfparm(dev, noinfo, &modesel, &hinfo, dsknames[pfmt[i]].ob_spec,id)!= 0) {
  479.       return ERROR;
  480.   }
  481.   
  482.   /* get data pattern to test the disk */
  483.   if (wgetnum("dp", &pattern) != OK) {
  484.       pattern = longrandom();  /* can't find pattern from wincap, make one */
  485.   } else {
  486.       temp = pattern;
  487.       pattern <<= 16;    /* shift pattern to hi word */
  488.       pattern |= temp;
  489.   }
  490.  
  491.  
  492.   br = (dev > 7) ? (dev-8) : (dev);    /* minus 8 for the scsi drive number */
  493.   /*
  494.    * One last chance to bail out.
  495.    */
  496.   *seldev = br + '0';
  497.   (fmtfnl[FUNIT].ob_spec)->te_ptext = seldev;
  498.   fmtfnl[FMTYES].ob_state = NORMAL;
  499.   fmtfnl[FMTNO].ob_state = NORMAL;
  500.   if (execform(fmtfnl) != FMTYES) return BAILOUT;
  501.  
  502.   /* For REAL !! */  
  503.   dsplymsg(fmtmsg);
  504.  
  505.   bsl = 0L;
  506.   
  507.   /* Get size of Bad Sector List */
  508.   if ((bslsiz = gbslsiz(dev)) > 0L) {
  509.       /* Allocate memory for existing BSL */
  510.       if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  511.           ret = err(nomemory);
  512.           goto formend;
  513.       }
  514.       
  515.       /* Read in BSL */
  516.       if ((ret = rdbsl(dev)) != OK) {
  517.           /* Create a new BSL if current one is unusable */
  518.           if (creabsl(dev, NEW, 0L) != OK) {
  519.               ret = ERROR;
  520.               goto formend;
  521.           }
  522.       } else {
  523.             /* Remove USER BSL */
  524.             if (creabsl(dev, EXPAND, nument(VENDOR)) != OK) {
  525.                 ret = ERROR;
  526.                 goto formend;
  527.             }
  528.       }
  529.   } else if (bslsiz == 0L || bslsiz == ERROR) {    /* no bsl or read error */
  530.       if (creabsl(dev, NEW, 0L) != OK) {
  531.           ret = ERROR;
  532.           goto formend;
  533.       }
  534.   } else {    /* bslsiz == MDMERR; medium changed error */
  535.       ret = ERROR;
  536.       goto formend;
  537.   }
  538.   
  539.   /*
  540.    * In supervisor mode
  541.    * set disk format parameters
  542.    * and format the disk.
  543.    */
  544.   ostack = Super(NULL);
  545.   v = OK;                    /* assume everything is OK */
  546.   w = -1;
  547.   if (modesel)    {            /* normal mode select ? */
  548.       v = ms(dev, &hinfo);    /* Yes, do noprmal mode set */
  549.       if (v == OK) w = OK;
  550.         /* Find formatted capacity of drive */
  551.       hdsiz = (long)hinfo.hi_cc * (long)hinfo.hi_dhc * (long)hinfo.hi_spt;
  552.   }    else {                    /* No, do special mode set */
  553.       set = typedev & (mask << dev);
  554.     scsidrv = typedrv & (mask << dev);
  555.     bsiz = ((set) || (scsidrv)) ? (16) : (22);
  556.     for (i = 0; i < 32; i++)
  557.         sendata[i] = 0;
  558.     if ((set) || (scsidrv))    {
  559.           v = mdsense(dev, 4, 0, 32, sendata);
  560.           for (i = 0; i < 32; i++) /* the lenght of sendata */
  561.               if (sendata[i])
  562.                 break;
  563.           if (i == 32)    { /* no infomations returned */
  564.             ret = 111;        
  565.             delay();
  566.             goto jjj;
  567.           }
  568.         hdsiz = get3bytes(sendata+5);
  569.           delay();                    /* kludge delay */
  570.         v = sqms(dev, sendata);
  571.         delay();
  572.         goto kkk;
  573.     }
  574. jjj:
  575.       if ((v = mdsense(dev, 0, 0, bsiz, sendata)) == OK)        {
  576.           for (i = 0; i < bsiz; i++)
  577.               if (sendata[i])
  578.                 break;
  579.           if (i == bsiz)    { /* no infomations returned */
  580.             ret = 111;        
  581.             delay();
  582.               Super(ostack);
  583.             goto formend;
  584.           }
  585.         hdsiz = get3bytes(sendata+5);
  586.           delay();                    /* kludge delay */
  587.         v = sqms(dev, sendata);
  588.     } else {
  589.           for (i = 0; i < bsiz; i++)
  590.               if (sendata[i])
  591.                 break;
  592.           if (i == bsiz)    { /* no infomations returned */
  593.             ret = 111;        
  594.             delay();
  595.               Super(ostack);
  596.             goto formend;
  597.           }
  598.     }
  599.  
  600. kkk:
  601.      delay();                    /* kludge delay */
  602.     w = OK;
  603.     if (dev > 7)                /* the drive is scsi */
  604.         if ((w = readcap(dev, 0, (long)0, buf)) == OK)
  605.             hdsiz = get4bytes(buf) + 1;
  606.   }
  607.   disksiz = hdsiz;
  608.   delay();                    /* kludge delay */
  609.   if ((v == OK) || (w == OK))
  610.       v = format(dev, (UWORD)hinfo.hi_in);  /* format */
  611.   delay();                    /* kludge delay */
  612.   Super(ostack);
  613.   
  614.   if ((v != 0) || (w != 0)) {
  615.       ret = errcode(dev);
  616.       if (tsterr(ret) != OK)
  617.           formaterr(dev);
  618.       ret = ERROR;
  619.       goto formend;
  620.   }
  621.   
  622.   ret = OK;
  623.   rebootp = 1;
  624. formend:
  625.   erasemsg();    /* Erase formatting box */
  626.   if (ret == 111)        /* HDX may not support this drive */
  627.           ret = err(needinfo);
  628.   if (ret < 0) {
  629.       if (bsl > 0) free(bsl);
  630.       return ERROR;
  631.   }
  632.   
  633.   /*------------------------------------------*
  634.    * Markbad the device destructively.          *
  635.    * Bad Sectors found are added to the BSL.  *
  636.    * Write BSL to device.              *
  637.    *------------------------------------------*/
  638.   if ((nbad = dsmarkbad(dev, hdsiz, 1, pattern)) < 0) {
  639.       free(bsl);
  640.       return ERROR;
  641.   }
  642.   if (wrbsl(dev) != OK) {
  643.       free(bsl);
  644.       return ERROR;
  645.   }
  646.   free(bsl);
  647.  
  648.     
  649.   /*
  650.    * Install boot-stopper in sector image;
  651.    * write root sector to device.
  652.    * 6-13-88  Setting of soft format parameters in root sector sets
  653.    *        the hard disk size only.
  654.    */
  655.   fillbuf(bs, 512L, 0L);    /* create new root sector */
  656.   sbslparm(bs);            /* set BSL parameters */
  657.   if (modesel)    {
  658.       sfmtparm(bs, &hinfo);
  659.   } else {
  660.       sdisksiz(bs, disksiz);
  661.   }
  662.   for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;)
  663.     *d++ = *s++;
  664.   Protobt(bs, -1L, -1, 1);    /* make root sector executable */
  665.   
  666.   if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  667.       if (tsterr(ret) != OK)
  668.           err(rootwrit);
  669.       return ERROR;
  670.   }
  671.  
  672.   /*
  673.    * Make a copy of the default partition name.
  674.    * Figure out the partition scheme id.
  675.    */
  676.   if (!noinfo)    {
  677.       s = wgetstr("pt");
  678.       strcpy(pnam, s);
  679.   }
  680.   /* ??
  681.   figprid(disksiz, pr_id);
  682.   */
  683.   dodipart(dev, pnam, disksiz);
  684.   return OK;
  685. }
  686.  
  687.  
  688.  
  689. /*
  690.  * Handle [PARTITION] item;
  691.  * if `xdev' is -1, throw up dialog boxes;
  692.  * if `xdev' >= 0, just partition the dev,
  693.  * using `pnam' as the partition type, 
  694.  * and `pr_id' to search for the type.
  695.  *
  696.  */
  697. dodipart(xdev, pnam, hsize)
  698. int xdev;
  699. char *pnam;
  700. long hsize;
  701. {
  702.     int dev, i, ret =OK, fine;
  703.     int choice;
  704.     char *seldev = "X";
  705.     char *s;
  706.     char bs[512];
  707.     PART *pinfo;
  708.     int tem1, tem2;
  709.     long disksiz;
  710.     extern long getdsiz();
  711.     int mask = 0x0001;
  712.  
  713.     if (xdev < 0) {
  714.     /*
  715.      * Throw up warning saying that partition is dangerous;
  716.      * then get physical dev they want to clobber.
  717.      */
  718.     pwarning[PWARNCN].ob_state = NORMAL;
  719.     pwarning[PWARNOK].ob_state = NORMAL;
  720.     if (execform(pwarning) != PWARNOK) return BAILOUT;
  721.     tformat = FALSE;
  722.     if ((dev = gphysdev()) < 0) {
  723.         return BAILOUT;
  724.     }
  725.     /*
  726.      * Let the user edit/pick partitions.
  727.      */
  728.     fine = 0;
  729.     while (!fine) {
  730.         if (sfigpart(bs, dev, (PART *)&pinfo) != OK)    {
  731.             if (pinfo > 0)    Mfree(pinfo);
  732.             return BAILOUT;
  733.         }
  734.         if ((ret = chkpart(dev, pinfo)) != OK) {
  735.             if (ret < 0)    {    /* size too big */
  736.                 err(nexsmem);
  737.             } else {    /* some other errors  */
  738.                 if (pinfo > 0)    Mfree(pinfo);
  739.                 return BAILOUT;
  740.             }
  741.         } else {
  742.             fine = 1;
  743.         }
  744.     }
  745.  
  746.       fine = (dev > 7) ? (dev-8) : (dev);    /* minus 8 for the scsi drive number */
  747.     /* Last chance to bail out */
  748.     *seldev = fine + '0';
  749.     (partfnl[PUNIT].ob_spec)->te_ptext = seldev;
  750.     partfnl[PARTYES].ob_state = NORMAL;
  751.     partfnl[PARTNO].ob_state = NORMAL;
  752.     if (execform(partfnl) != PARTYES)    {
  753.         if (pinfo > 0)    Mfree(pinfo);
  754.         return BAILOUT;
  755.     }
  756.  
  757.     } else {
  758.         /* ??
  759.         if ((!noinfo) && (!ttscsi) && (wgetent(pnam, pr_id) != OK)) {
  760.             nopart[NOSCHPOK].ob_state = NORMAL;
  761.             (nopart[NOSCHPR].ob_spec)->te_ptext = pnam;
  762.             execform(nopart);
  763.             return ERROR;
  764.         }
  765.         */
  766.         npart = 4;
  767.         ext = NO_EXT;    /* set the extended partition flag to not exists */
  768.         dev = xdev;
  769.         if ((pinfo = (PART *)Malloc((long)sizeof(PART)*npart)) <= 0)    {
  770.             err(nomemory);
  771.             if (pinfo > 0)    Mfree(pinfo);
  772.             return ERROR;
  773.         }
  774.         inipart(pinfo, npart);
  775.         npart = 0;
  776.         setpart(pinfo, pnam, hsize);
  777.         /* ??
  778.         if (ttscsi)        {     SCSI bus drive 
  779.             setpart(pinfo, hsize);
  780.         } else {             regular drvie 
  781.             for (i = 0; i < 4; ++i)
  782.                 fillpart(i, &pinfo[i]);
  783.         }
  784.         */
  785.     }
  786.  
  787.     /* For REAL!! */
  788.     dsplymsg(partmsg);
  789.     
  790.     bsl = 0L;
  791.     
  792.     /* Get size of BSL */
  793.     if ((bslsiz = gbslsiz(dev)) > 0L) {
  794.         /* Allocate memory for existing BSL */
  795.         if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  796.             ret = err(nomemory);
  797.             goto partend;
  798.         }
  799.             
  800.         /* Read in BSL */
  801.         if ((ret = rdbsl(dev)) != OK) {
  802.             if (ret == INVALID)
  803.                 err(cruptbsl);
  804.             ret = ERROR;
  805.             goto partend;
  806.         }
  807.     } else if (bslsiz == 0) {
  808.         ret = err(oldfmt);
  809.         goto partend;
  810.     } else if (bslsiz == ERROR) {
  811.         ret = err(rootread);
  812.         goto partend;
  813.     } else {
  814.         ret = ERROR;
  815.         goto partend;
  816.     }
  817.  
  818.     
  819.     /* Lay out partition headers */
  820.     if (spheader(dev, &pinfo[0]) != OK) {
  821.         ret = ERROR;
  822.         goto partend;
  823.     }
  824.     
  825.     if (wrbsl(dev) != OK) {        /* write BSL */
  826.         ret = ERROR;
  827.         goto partend;
  828.     }
  829.  
  830.     /* check and change the structure's id after 'spheader()' */
  831.     changeid(pinfo);
  832.  
  833.     /* Shove partition parms into root sector */
  834.     if ((ret = getroot(dev, bs, (SECTOR)0)) != 0)    {
  835.         if (tsterr(ret) != OK)
  836.             err(rootread);
  837.         ret = ERROR;
  838.         goto partend;
  839.     }
  840.  
  841.     if ((ret = stlayroot(bs, dev, pinfo)) != OK)    {
  842.         goto partend;
  843.     }
  844.     tem1 = npart;            /* save the number of partitions */
  845.     tem2 = ext;                /* save the index of extended partition */
  846.     if (rescan(1,0)) {        /* has to be here because map changed    */
  847.         ret = ERROR;        /* after partitions are moved around,    */
  848.         goto partend;        /* report medium change error.        */
  849.     }
  850.     npart = tem1;
  851.     ext = tem2;
  852.     /* Partition the device with parameters given in pinfo */
  853.     if (stlaybs(dev, &pinfo[0]) != OK)
  854.         ret = ERROR;
  855.     else
  856.         ret = OK;
  857.         
  858.     rebootp = 1;
  859.     /*
  860.     if ((typedev & (mask << dev)))             it is a removable drive 
  861.         if (npart <= prevnpart)                 if less or equal than prevous 
  862.             rebootp = 0;                      partition, don't reboot 
  863.     */
  864.     pnf = 1;        /* set the flag to just doing the partition */
  865. partend:
  866.     if (bsl > 0) free(bsl);
  867.     inipart(pinfo, npart);
  868.     if (pinfo > 0)    Mfree(pinfo);
  869.     erasemsg();
  870.     return (ret);
  871. }
  872.  
  873.  
  874. /*
  875.  * get root sector informations and write them into that sector 
  876.  */
  877.  
  878. stlayroot(bs, dev, part)
  879. char *bs;
  880. int dev;
  881. PART *part;
  882. {
  883.     int i;
  884.     UWORD sum = 0x1234;
  885.     long cnt, disksiz, prvst;
  886.     char *d, *s;
  887.     extern char bootstop;
  888.     extern char bootend;
  889.  
  890.     /* do the prime partition */
  891.     spart(bs, part, 0, &prvst);    /* set ST partition parameters */
  892.     /*
  893.       sfmtparm(bs, &hinfo);
  894.       for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;)
  895.         *d++ = *s++;
  896.     */
  897.     sbslparm(bs);                /* set bsl parameters */
  898.     Protobt(bs, -1L, -1, 1);        /* make root sector executable */
  899.     if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  900.         if (tsterr(ret) != OK)
  901.             err(rootwrit);
  902.         return(ERROR);
  903.     }
  904.     if (ext == NO_EXT)    return OK;        /* no extended partition */
  905.     /* do the extended partitions */
  906.     extsiz = part[ext].p_siz;
  907.     for (i = 4; i < npart; i++)    {
  908.         if (!(part[i].p_flg & P_EXISTS))    {     /* skip if not exists */
  909.             return OK;
  910.         }
  911.         spart(bs, part, i, &prvst);    /* set IBM partition parameters */
  912.         if ((ret = putroot(dev, bs, part[i].p_st)) != OK) {
  913.             if (tsterr(ret) != OK)
  914.                 err(rootwrit);
  915.             return(ERROR);
  916.         }
  917.     }
  918.     return OK;
  919. }
  920.  
  921.  
  922.  
  923.  
  924. /*
  925.  * Put information into the root structure
  926.  */
  927.  
  928. spart(image, pinfo, pnm, prvst)
  929.  
  930. char *image;            /* root sector buffer */
  931. register PART *pinfo;    /* partition information */
  932. int pnm;                /* partition number */
  933. long *prvst;            /* The previous partition start sector */
  934.  
  935. {
  936.     PART *rpart;
  937.     long numcyl;
  938.     int i, j;
  939.  
  940.     if (pnm)     {
  941.         fillbuf(image, 512L, 0L);
  942.     }
  943.     rpart = &((RSECT *)(image + 0x200 - sizeof(RSECT)))->hd_p[0];
  944.     if (pnm < 4)    {
  945.         for (i = 0; i < NPARTS; i++, rpart++)    {
  946.             if (pinfo->p_flg & P_EXISTS)    {
  947.                 rpart->p_flg = P_EXISTS;
  948.                 for (j = 0; j < 3; j++)
  949.                     rpart->p_id[j] = pinfo->p_id[j];
  950.                 rpart->p_st = pinfo->p_st;
  951.                 rpart->p_siz = pinfo->p_siz;
  952.             } else {
  953.                 rpart->p_flg = 0;
  954.                 for (j = 0; j < 3; j++)
  955.                     rpart->p_id[j] = 0;
  956.                 rpart->p_st = 0L;
  957.                 rpart->p_siz = 0L;
  958.             }
  959.             pinfo++;
  960.         }
  961.  
  962.     } else {    /* pnm => 4 */
  963.         rpart->p_flg = pinfo[pnm].p_flg;
  964.         for (j = 0; j < 3; j++)
  965.             rpart->p_id[j] = pinfo[pnm].p_id[j];
  966.         rpart->p_st = ROOTSECT;
  967.         rpart->p_siz = pinfo[pnm].p_siz - ROOTSECT;
  968.         rpart++;
  969.         if (((pnm + 1) != npart) && (pinfo[pnm+1].p_flg & P_EXISTS)) { 
  970.             /* need extened partition */
  971.             rpart->p_flg = P_EXISTS;
  972.             rpart->p_id[0] = 'X';
  973.             rpart->p_id[1] = 'G';
  974.             rpart->p_id[2] = 'M';
  975.             rpart->p_siz = pinfo[pnm+1].p_siz;
  976.             rpart->p_st = (pnm == 4) ? (pinfo[4].p_siz) :
  977.                                     (pinfo[pnm].p_siz + *prvst);
  978.             *prvst = rpart->p_st;
  979.         }
  980.  
  981.     }
  982. }
  983.  
  984.  
  985.  
  986. /*
  987.  * Setup partitions on the disk;
  988.  * write boot sectors and zero FATs and root directories.
  989.  *
  990.  */
  991. stlaybs(physdev, pinfo)
  992. int physdev;
  993. register PART *pinfo;
  994. {
  995.     int i, ldev, ret;
  996.     int kindfat;
  997.     SECTOR data, nsect;
  998.     char *devno="X";
  999.     long ndirs;
  1000.     UWORD fatsiz;
  1001.     BOOT *bs;
  1002.     long serialno;
  1003.     extern long longrandom();
  1004.     extern long cell();
  1005.     char *buf;
  1006.     long size;
  1007.  
  1008.     if ((bslsiz = gbslsiz(physdev)) < 0L) {
  1009.         if (bslsiz == ERROR)
  1010.             err(rootread);
  1011.         return ERROR;
  1012.     }
  1013.     /* SCAN_BS: pinfo is for scan() and laybs() use */
  1014.     if (ext != NO_EXT)    sortpart(pinfo, SCAN_BS);    
  1015.  
  1016.     for (i = 0; i < npart; ++i, ++pinfo) {
  1017.         
  1018.         /* don't care if partition does not exist */
  1019.         if (!(pinfo->p_flg & P_EXISTS)) {
  1020.             return OK;
  1021.         }
  1022.  
  1023.  
  1024.     /*
  1025.      * Compute boot sector parameters.
  1026.      */
  1027.         if (pinfo->p_siz > disksiz) {        /* partition >? disk size */
  1028.             *devno = i + '0';
  1029.             (part2big[BGPART].ob_spec)->te_ptext = devno;
  1030.             part2big[BGPARTOK].ob_state = NORMAL;
  1031.             execform(part2big);
  1032.             return ERROR;
  1033.         }
  1034.  
  1035.     /* estimat the bps */
  1036.     /* MAXSECT = 16MB - 8 */
  1037.     bps = cell((pinfo->p_siz-7)*BPS, (long)MAXSECT);
  1038.  
  1039.     /* the real bps */
  1040.     bps = BPS * n2power((UWORD)cell(bps, (long)BPS));
  1041.     ratio = bps / BPS;
  1042.     nsect = pinfo->p_siz / ratio;
  1043.  
  1044.     size = (long)BPS * ratio;
  1045.     if ((buf = (char *)Malloc(size)) <= 0)    {
  1046.         err(nomemory);
  1047.         if (buf > 0) Mfree((long)buf);
  1048.         return ERROR;
  1049.     }
  1050.  
  1051.     /*
  1052.      * Install entries in boot sector image;
  1053.      * force sector checksum to zero (non-executable);
  1054.      * write boot sector to media.
  1055.      *
  1056.       *    512 bytes/sector
  1057.      *    2 or 4 sectors/cluster (partition > 16Mb has 4 spc)
  1058.      *    1 reserved sector (for boot)
  1059.      *    2 FATs
  1060.      *    ... dir slots
  1061.      *    ... # sectors
  1062.      *    F8 means media is a hard disk
  1063.      *    ... FAT size
  1064.      *
  1065.      */
  1066.      
  1067.     /* Make a clean boot sector */
  1068.     fillbuf(buf, bps, 0L);
  1069.     bs = (BOOT *)buf;
  1070.         
  1071.  
  1072.     /* bytes per sector */
  1073.     iw((UWORD *)&bs->b_bps[0], (UWORD)bps);
  1074.     
  1075.     /* sectors per cluster */
  1076.     bs->b_spc = SPC;
  1077.         
  1078.     /* number of reserved sectors */
  1079.     iw((UWORD *)&bs->b_res[0], (UWORD)1);
  1080.     
  1081.     /* number of FATs */
  1082.     bs->b_nfats = 2;
  1083.     
  1084.  
  1085.     /*
  1086.      * Compute root directory size
  1087.      * 256 entries, plus fudge on devs > 10Mb
  1088.      */
  1089.     if (pinfo->p_siz < 0x5000L) ndirs = NUMEN;
  1090.     else ndirs = nsect / 80;    /* 1 dir entry per 80 sectors */
  1091.     /* round to nearest sector */
  1092.     ndirs = (ndirs + ((UWORD)bps/BPDIR - 1)) & ~((UWORD)bps/BPDIR - 1);    
  1093.     iw((UWORD *)&bs->b_ndirs[0], (UWORD)ndirs);
  1094.     
  1095.     /* number of sectors on media (partition) */
  1096.     iw((UWORD *)&bs->b_nsects[0], (UWORD)nsect);
  1097.  
  1098.     /* media descriptor */
  1099.     bs->b_media = 0xf8;
  1100.  
  1101.     /*--------------------------------------------------------------*
  1102.      * Compute FAT size                        *
  1103.      *                                *
  1104.      * Num entries to map the entire partition            *
  1105.      *    = partition's size in clusters                *
  1106.      *    = partition's size in sectors / spc            *
  1107.      *                                *
  1108.      * Num entries in FAT                        *
  1109.      *    = Num entries to map partition + reserved entries    *
  1110.      *    = (partition's size in sectors / spc) + 2        *
  1111.      *                                *
  1112.      * Num sectors FAT occupies                    *
  1113.      *    = Num entries in FAT / Num entries of FAT per sector    *
  1114.      *    = Num entries in FAT / (512 / 2)    <16-bit FAT>    *
  1115.      *    = ((partition's size in sectors / spc) + 2) / 256 + 1    *
  1116.      *                        <+1 to round up>    *
  1117.      *--------------------------------------------------------------*/
  1118.     fatsiz = ((((nsect / bs->b_spc) + 2) * 2) / bps) + 1;
  1119.     iw((UWORD *)&bs->b_spf[0], (UWORD)fatsiz);
  1120.  
  1121.     /* write the serial number to the bs */ 
  1122.     Protobt(bs, 0x01000000, -1, -1);
  1123.  
  1124.     /*
  1125.      * Write partition's boot sector
  1126.      */
  1127.     forcesum((UWORD *)buf, (UWORD)0);    /* force image checksum */
  1128.     if ((ret = wrsects(physdev,(UWORD)ratio,buf,(SECTOR)pinfo->p_st))!= OK) {
  1129.         if (tsterr(ret) != OK)
  1130.             err(bootwrit);
  1131.         return ERROR;
  1132.     }
  1133.  
  1134.     /*
  1135.      * Zero the partition
  1136.      */
  1137.     if ((ret = zerosect(physdev, (SECTOR)(pinfo->p_st+ratio),
  1138.              ((UWORD)((fatsiz*2 + ndirs*BPDIR/bps) * ratio)))) != OK) {
  1139.         if (tsterr(ret) != OK)
  1140.             err(hdrwrite);
  1141.         return ERROR;
  1142.     }
  1143.              
  1144.     /*
  1145.      * Make first 2 entries in FATs more IBM-like.
  1146.      */
  1147.     if ((ret = rdsects(physdev,(UWORD)ratio,buf,
  1148.                         (SECTOR)(pinfo->p_st+ratio)))!= 0){
  1149.         if (tsterr(ret) != OK)
  1150.             err(fatread);
  1151.         return ERROR;
  1152.     }
  1153.     *(UWORD *)&buf[0] = 0xf8ff;
  1154.     *(UWORD *)&buf[2] = 0xffff;
  1155.     if ((ret = wrsects(physdev,(UWORD)ratio,
  1156.                         buf,(SECTOR)(pinfo->p_st+ratio)))!= 0 ||
  1157.         (ret = wrsects(physdev,(UWORD)ratio,buf,
  1158.                         (SECTOR)(pinfo->p_st+ratio+fatsiz*ratio)))
  1159.         != 0) {
  1160.         if (tsterr(ret) != OK)
  1161.             err(fatwrite);
  1162.         return ERROR;
  1163.     }
  1164.  
  1165.     /*
  1166.      * Mark bad sectors recorded in the BSL into the FATs.
  1167.      * Calculating parameters:
  1168.      *    ldev - from physdev and i.
  1169.      *    fat0 - always equals 1.
  1170.      *    fatsiz - calculated above.
  1171.      *    data - starts after the boot sector, 2 FATs and rootdir.
  1172.      */
  1173.  
  1174.         if (bslsiz > 0) {
  1175.             if ((ldev = phys2log(physdev, i)) == ERROR)
  1176.                 return parterr(physdev);
  1177.             data = (SECTOR)1 + (SECTOR)(fatsiz*2) + (SECTOR)(ndirs*BPDIR/bps);
  1178.             bsl2fat(ldev, (SECTOR)ratio, (UWORD)(fatsiz*ratio), 
  1179.                                                 data*ratio, MEDIA);
  1180.         }
  1181.         if (buf > 0) Mfree((long)buf);
  1182.     }
  1183.     return OK;
  1184. }
  1185.  
  1186.  
  1187.  
  1188.  
  1189. /*
  1190.  * Handle [ZERO] item.
  1191.  *
  1192.  */
  1193. dodizero()
  1194. {
  1195.     int ldev, ret;
  1196.     char *seldev = "X";
  1197.     int i; 
  1198.  
  1199.     zwarning[ZWOK].ob_state = NORMAL;
  1200.     zwarning[ZWCN].ob_state = NORMAL;
  1201.     if (execform(zwarning) != ZWOK)
  1202.     return BAILOUT;
  1203.     if (showmany)    err(manyldev);
  1204.  
  1205.     if ((ldev = glogdev()) < 0) return BAILOUT;
  1206.  
  1207.     /* Find out if logical device has assumed parameters */
  1208.     if (chkparm(ldev) != OK) {
  1209.         wronparm[WRONOK].ob_state = NORMAL;
  1210.     execform(wronparm);
  1211.     return ERROR;
  1212.     }
  1213.         
  1214.     *seldev = ldev;
  1215.     (zerofnl[ZDRV].ob_spec)->te_ptext = seldev;
  1216.     strcat((zerofnl[ZDRV].ob_spec)->te_ptext, ":");
  1217.     zerofnl[ZYES].ob_state = NORMAL;
  1218.     zerofnl[ZNO].ob_state = NORMAL;
  1219.     if (execform(zerofnl) != ZYES)  return BAILOUT;
  1220.  
  1221.     dsplymsg(zeromsg);
  1222.     if (zero(ldev) == OK) {
  1223.     if (!rebootp) {
  1224.         for (i = 0; i < 10; i++) {
  1225.         if (!mediach(ldev-'A')) break;
  1226.         }
  1227.         if (i == 10) {
  1228.             rebootp = 1;
  1229.         err(mdach);
  1230.             }
  1231.     }
  1232.     }
  1233.     erasemsg();
  1234. }
  1235.  
  1236.  
  1237. /*
  1238.  * Handle [MARKBAD] item.
  1239.  *
  1240.  */
  1241. dodimark()
  1242. {
  1243.     int ldev, ret;
  1244.     int i;
  1245.  
  1246.     mwarning[MWARNOK].ob_state = NORMAL;
  1247.     mwarning[MWARNCN].ob_state = NORMAL;
  1248.     if (execform(mwarning) == MWARNCN)
  1249.         return BAILOUT;
  1250.     if (showmany)    err(manyldev);
  1251.  
  1252.     if ((ldev = glogdev()) < 0)
  1253.         return BAILOUT;
  1254.         
  1255.     /* Find out if logical device has assumed parameters */
  1256.     if (chkparm(ldev) != OK) {
  1257.         wronparm[WRONOK].ob_state = NORMAL;
  1258.     execform(wronparm);
  1259.     return ERROR;
  1260.     }
  1261.          
  1262.     dsplymsg(lmrkmsg);
  1263.     if (markbad(ldev) != OK) {
  1264.         erasemsg();
  1265.     } else {
  1266.         if (!rebootp) {
  1267.         for (i = 0; i < 10; i++) {
  1268.         if (!mediach(ldev-'A')) break;
  1269.         }
  1270.         if (i == 10) {
  1271.             rebootp = 1;
  1272.         err(mdach);
  1273.             }
  1274.         }
  1275.     }
  1276. }
  1277.  
  1278.  
  1279. /*
  1280.  * Map from button in ship dial.
  1281.  */
  1282. int sdev[] = {
  1283.     SDEV0, SDEV1, SDEV2, SDEV3,
  1284.     SDEV4, SDEV5, SDEV6, SDEV7
  1285. };
  1286.  
  1287. /*
  1288.  * Ship selected devices.
  1289.  */
  1290. dodiship()
  1291. {
  1292.   int i, seldev[16], selected=0;
  1293.   int j, endup, index, doscsi;
  1294.   
  1295.     doscsi = 0;
  1296.     index = 0;
  1297.  
  1298.   /* Throw up generic shipping warning. */
  1299.   shipdial[SWARNCN].ob_state = NORMAL;
  1300.   shipdial[SWARNOK].ob_state = NORMAL;
  1301.   if (execform(shipdial) != SWARNOK) return BAILOUT;
  1302.   
  1303.   /* Device(s) selected? */
  1304.   shipdev[SDEVOK].ob_state = NORMAL;
  1305.   shipdev[SDEVCN].ob_state = NORMAL;
  1306.   for(i = 0; i < 8; i++)     /* indicate what's alive */
  1307.         shipdev[sdev[i]].ob_state = DISABLED;
  1308.   endup = index + 8;
  1309.   for(i = index, j = 0; i < endup; i++, j++)     /* indicate what's alive */
  1310.         if (livedevs[i])
  1311.             shipdev[sdev[j]].ob_state = NORMAL | SHADOWED;
  1312.   
  1313.   if (execform(shipdev) != SDEVOK)
  1314.       return BAILOUT;
  1315.       
  1316.   for(i = 0; i < 8; i++) {    /* search for selected unit */
  1317.       if (shipdev[sdev[i]].ob_state & SELECTED) {
  1318.           seldev[i+index] = 1;
  1319.           selected++;
  1320.       } else {
  1321.             seldev[i+index] = 0;
  1322.       }
  1323.   }
  1324.   
  1325.   if (!selected) return BAILOUT;    /* nothing is selected */
  1326.   
  1327.   /* Throw up final shipping warning. */
  1328.   shipfnl[SFNLCN].ob_state = NORMAL;
  1329.   shipfnl[SFNLOK].ob_state = NORMAL;
  1330.   if (execform(shipfnl) != SFNLOK) return BAILOUT;
  1331.   
  1332.   /* For REAL!!! */
  1333.   /* Ship selected devices */
  1334.   for (i = 0; i < MAXPHYSDEV; i++) {
  1335.       if (seldev[i])
  1336.           ship(i);
  1337.   }
  1338.   
  1339.   /* Put out final message about turning off hard disks */
  1340.   scommand[TRNOFFOK].ob_state = NORMAL;
  1341.   execform(scommand);
  1342. }
  1343.  
  1344.  
  1345.  
  1346. /*
  1347.  * Translate unit number to tree index.
  1348.  *
  1349.  */
  1350. static int physxlat[] = {
  1351.     UNIT0, UNIT1, UNIT2, UNIT3,
  1352.     UNIT4, UNIT5, UNIT6, UNIT7
  1353. };
  1354.  
  1355.  
  1356. /*
  1357.  * Get physical device#,
  1358.  * return devno or -1.
  1359.  *
  1360.  */
  1361. gphysdev()
  1362. {
  1363.     int i, j, endup, start, index, doscsi;
  1364.  
  1365.     /* Set up the dialog box for SCSI or ACSI driver selection */
  1366. redogphy:
  1367.         doscsi = 0;
  1368.         index = 0;
  1369.     /*
  1370.      * Clean up and exec object;
  1371.      * shadow devs we KNOW are there.
  1372.      */
  1373.     physdial[PHYSOK].ob_state = NORMAL;
  1374.     physdial[PHYSCN].ob_state = NORMAL;
  1375.     
  1376.     if (tformat == TRUE) {
  1377.         start = 1;        /* start initializing at unit 0 */
  1378.         physdial[physxlat[0]].ob_state = NORMAL;
  1379.     } else {
  1380.         start = 0;        /* start initializing at unit 1 */
  1381.     }
  1382.     
  1383.     for (i = start; i < 8; ++i)
  1384.         physdial[physxlat[i]].ob_state = DISABLED;
  1385.     /*
  1386.     if (ttscsi)             the hard drive is a SCSI drive 
  1387.         physdial[physxlat[8]].ob_state = NORMAL;
  1388.     */
  1389.     endup = index + 8;
  1390.     for (i = index, j = 0; i < endup; ++i, j++)
  1391.         if (livedevs[i])
  1392.             physdial[physxlat[j]].ob_state = NORMAL | SHADOWED;
  1393.  
  1394.     if (execform(physdial) != PHYSOK)
  1395.         return ERROR;
  1396.      
  1397.     /* search for the selected unit */
  1398.     for (i = 0; i < 8; ++i)
  1399.         if (physdial[physxlat[i]].ob_state & SELECTED)    {
  1400.             if (livedevs[index+i])
  1401.                 return(index+i);
  1402.             else    {    
  1403.                 form_alart(1, nodev);
  1404.                 goto redogphy;
  1405.             }
  1406.         }
  1407.  
  1408.  
  1409.     return ERROR;            /* if no object selected */
  1410. }
  1411.  
  1412.  
  1413. /*
  1414.  * Translate from logical device number
  1415.  * to object number in logical device
  1416.  * dialouge box.
  1417.  */
  1418. int logxlat[] = {
  1419.     CCOLON, DCOLON, ECOLON, FCOLON,
  1420.     GCOLON, HCOLON, ICOLON, JCOLON,
  1421.     KCOLON, LCOLON, MCOLON, NCOLON,
  1422.     OCOLON, PCOLON
  1423. };
  1424.  
  1425.  
  1426. /*
  1427.  * Get logical device,
  1428.  * return 'C'...'P'
  1429.  * or -1.
  1430.  *
  1431.  */
  1432. glogdev()
  1433. {
  1434.     int i, flg;
  1435.  
  1436.     /*
  1437.      * Setup tree; selectively enable drive buttons
  1438.      * and so on.
  1439.      */
  1440.     logdial[LOGOK].ob_state = NORMAL;
  1441.     logdial[LOGCN].ob_state = NORMAL;
  1442.     for (i = 0; i < MAXLOGDEVS; ++i) {
  1443.     if (logmap[i].lm_physdev < 0)
  1444.         flg = DISABLED;
  1445.         else flg = NORMAL;
  1446.     logdial[logxlat[i]].ob_state = flg;
  1447.     }
  1448.  
  1449.     if (execform(logdial) != LOGOK) return -1;
  1450.  
  1451.     for (i = 0; i < MAXLOGDEVS; ++i)
  1452.     if (logdial[logxlat[i]].ob_state & SELECTED)
  1453.         return i + 'C';
  1454.  
  1455.     return -1;
  1456. }
  1457.  
  1458.  
  1459. /*
  1460.  * Open virtual workstation.
  1461.  *
  1462.  */
  1463. open_vwork()
  1464. {
  1465.     int i;
  1466.  
  1467.     for (i = 0; i < 10;)
  1468.     work_in[i++] = 1;
  1469.     work_in[10] = 2;
  1470.     handle = phys_handle;
  1471.     v_opnvwk(work_in, &handle, work_out);
  1472. }
  1473.  
  1474.  
  1475. /*
  1476.  * Find and redraw all clipping rectangles
  1477.  *
  1478.  */
  1479. do_redraw(xc, yc, wc, hc)
  1480. int xc, yc, wc, hc;
  1481. {
  1482.     GRECT t1, t2;
  1483.     int temp[4];
  1484.  
  1485.     hide_mouse();
  1486.     t2.g_x=xc;
  1487.     t2.g_y=yc;
  1488.     t2.g_w=wc;
  1489.     t2.g_h=hc;
  1490.     vsf_interior(handle, 1);
  1491.     vsf_color(handle, 0);
  1492.     wind_get(wi_handle, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  1493.     while (t1.g_w && t1.g_h) {
  1494.     if (rc_intersect(&t2, &t1)) {
  1495.         set_clip(t1.g_x, t1.g_y, t1.g_w, t1.g_h);
  1496.         temp[0] = xwork;
  1497.         temp[1] = ywork;
  1498.         temp[2] = xwork + wwork - 1;
  1499.         temp[3] = ywork + hwork - 1;
  1500.         v_bar(handle, temp);
  1501.     }
  1502.     wind_get(wi_handle, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  1503.     }
  1504.  
  1505.     show_mouse();
  1506. }
  1507.  
  1508.  
  1509. /*
  1510.  * Hide the mouse.
  1511.  *
  1512.  */
  1513. hide_mouse()
  1514. {
  1515.     if (!hidden) {
  1516.     graf_mouse(M_OFF, 0L);
  1517.     hidden = TRUE;
  1518.     }
  1519. }
  1520.  
  1521.  
  1522. /*
  1523.  * Show the mouse.
  1524.  *
  1525.  */
  1526. show_mouse() 
  1527. {
  1528.     if (hidden) {
  1529.     graf_mouse(M_ON, 0L);
  1530.     hidden = FALSE;
  1531.     }
  1532. }
  1533.  
  1534.  
  1535. /*
  1536.  * Set clipping rectangle.
  1537.  *
  1538.  */
  1539. set_clip(x, y, w, h)
  1540. int x, y, w, h;
  1541. {
  1542.     int clip[4];
  1543.  
  1544.     clip[0] = x;
  1545.     clip[1] = y;
  1546.     clip[2] = x + w;
  1547.     clip[3] = y + h;
  1548.     vs_clip(handle, 1, clip);
  1549. }
  1550.  
  1551.  
  1552. /*
  1553.  * "Execute" form,
  1554.  * return thingy that caused the exit.
  1555.  *
  1556.  */
  1557. execform(tree)
  1558. OBJECT tree[];
  1559. {
  1560.     int thingy;
  1561.  
  1562.     ARROW_MOUSE;
  1563.     dsplymsg(tree);
  1564.     thingy = form_do(tree, 0);
  1565.     erasemsg();
  1566.     BEE_MOUSE;
  1567.     return thingy;
  1568. }
  1569.  
  1570.  
  1571. /*
  1572.  *  Display a dialogue box on the screen.
  1573.  *    Input:
  1574.  *        tree - object tree for dialogue box to be displayed.
  1575.  *    Output:
  1576.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  1577.  */
  1578. dsplymsg(tree)
  1579. OBJECT *tree;
  1580. {
  1581.     form_center(tree,&lx, &ly, &formw, &formh);
  1582.  
  1583.     /*
  1584.     sx = lx + formw / 2;
  1585.     sy = ly + formh / 2;
  1586.     */
  1587.     
  1588.     form_dial(1, 0, 0, 0, 0, lx, ly, formw, formh);
  1589.     objc_draw(tree, 0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1590. }
  1591.  
  1592.  
  1593. /*
  1594.  *  Erase a dialogue box from the screen.
  1595.  *    Input:
  1596.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  1597.  */
  1598. erasemsg()
  1599. {
  1600.     form_dial(3, 0, 0, 0, 0, lx, ly, formw, formh);
  1601. }
  1602.  
  1603.  
  1604.  
  1605. /*
  1606.  *  Make a long (4-byte) random.
  1607.  */ 
  1608. long
  1609. longrandom()
  1610. {
  1611.     long pattern;
  1612.     
  1613.     pattern = Random();
  1614.     pattern <<= 16;
  1615.     pattern ^= Random();
  1616.     
  1617.     return (pattern);
  1618. }
  1619.  
  1620. changeid(part)
  1621. PART *part;
  1622. {
  1623.     int i;
  1624.     long psiz;
  1625.  
  1626.     for(i = 0; i < npart; i++)    {
  1627.         if (i == ext)    continue;
  1628.         if (!(part[i].p_flg & P_EXISTS)) return OK;
  1629.         if (i > 3)    {
  1630.             psiz = part[i].p_siz - ROOTSECT;
  1631.         } else {
  1632.             psiz = part[i].p_siz;
  1633.         }
  1634.         if (psiz < MB16)    {
  1635.             part[i].p_id[0] = 'G';
  1636.             part[i].p_id[1] = 'E';
  1637.             part[i].p_id[2] = 'M';
  1638.         } else {
  1639.             part[i].p_id[0] = 'B';
  1640.             part[i].p_id[1] = 'G';
  1641.             part[i].p_id[2] = 'M';
  1642.         }
  1643.     }
  1644. }
  1645.  
  1646.